package pers.bc.utils.spring;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RestController;

/**
 * SpringUtil工具类
 *
 * @fileRelativePath: SpringUtil.java
 * @Date: Created on 2021/9/24  9:27  <br>
 * @author: LiBencheng<br>
 * @version: 1.0<br>
 */
@Component
public class SpringHelper implements ApplicationContextAware
{

    private static ApplicationContext applicationContext = null;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { SpringHelper.applicationContext = applicationContext; }

    public static ApplicationContext getApplicationContext( ) { return applicationContext; }

    public static < T > T getBean(Class< T > cla) { return applicationContext.getBean(cla); }

    public static < T > T getBean(String name, Class< T > cal) { return applicationContext.getBean(name, cal); }

    public static Object getBean(String name) { return applicationContext.getBean(name); }

    public static String getProperty(String key){ return applicationContext.getBean(Environment.class).getProperty(key); }
    
    /**
     * *********************************************************** <br>
     * *说明： <br>
     * @see <br>
     * @return <br>
     * @List<String> <br>
     * @methods pers.bc.utils.spring.ControllerScanner#getAllControllerBeanNames <br>
     * @author LiBencheng <br>
     * @date Created on 2000年1月4日 <br>
     * @time 下午8:37:57 <br>
     * @version 1.0 <br>
     *************************************************************          <br>
     */
    public List<String> getAllControllerBeanNames()
    {
        List<String> allControllerBeans = new ArrayList<String>();
        // 获取所有被@RestController标记的Bean名称
        List<String> restControllerBeans = getAllComponentNames(RestController.class);
        // 合并并去重（因为@RestController是@Controller的特化）
        for (String beanName : restControllerBeans)
            allControllerBeans.add(beanName);

        // 获取所有被@Controller标记的Bean名称
        List<String> controllerBeans = getAllComponentNames(Controller.class);
        for (String beanName : controllerBeans)
            if (!allControllerBeans.contains(beanName))//
                allControllerBeans.add(beanName);
        
        return allControllerBeans;
    }
    
    /**
     * *********************************************************** <br>
     * *说明： 此方法会返回所有带有@RestController和@Controller的Bean实例 <br>
     * @see <br>
     * @return <br>
     * @Map<String,Object> <br>
     * @methods pers.bc.utils.spring.SpringHelper#getAllControllers <br>
     * @author LiBencheng <br>
     * @date Created on 2000年1月1日 <br>
     * @time 上午12:05:15 <br>
     * @version 1.0 <br>
     ************************************************************* <br>
     */
    public Map<String, Object> getAllControllers()
    { 
        Map<String, Object> controllers = getComponents(Controller.class);
        controllers.putAll(getComponents(RestController.class));
        
        return controllers;
    }
    
    
    /**
     * *********************************************************** <br>
     * *说明： <br>
     * @see <br>
     * @param annotationZlass
     * @return <br>
     * @List<String> <br>
     * @methods pers.bc.utils.spring.SpringHelper#getAllComponentNames <br>
     * @author LiBencheng <br>
     * @date Created on 2000年1月1日 <br>
     * @time 上午12:33:04 <br>
     * @version 1.0 <br>
     ************************************************************* <br>
     */
    public List<String> getAllComponentNames(final Class<? extends Annotation> annotationZlass)
    {
        // 获取所有被@RestController标记的Bean名称
        String[] restControllerBeans = applicationContext.getBeanNamesForAnnotation(annotationZlass);
        List<String> allControllerBeans = new ArrayList<String>();
        // 合并并去重（因为@RestController是@Controller的特化）
        for (int i = 0; i < restControllerBeans.length; i++)
            allControllerBeans.add(restControllerBeans[i]);
        
        return allControllerBeans;
    }
    
    /**
     * *********************************************************** <br>
     * *说明：获取对应Spring注解，对于的Bean <br>
     * @see <br>
     * @param AnnotationZlass
     * @return <br>
     * @Map<String,Object> <br>
     * @methods pers.bc.utils.spring.SpringHelper#getComponents <br>
     * @author LiBencheng <br>
     * @date Created on 2000年1月1日 <br>
     * @time 上午12:08:29 <br>
     * @version 1.0 <br>
     *************************************************************          <br>
     */
    public Map<String, Object> getComponents(final Class<? extends Annotation> annotationZlass)
    {return applicationContext.getBeansWithAnnotation(annotationZlass);}
    
}